feat(traces): Disable links to traces older than 30 days#112377
feat(traces): Disable links to traces older than 30 days#112377nsdeschenes wants to merge 39 commits intomasterfrom
Conversation
|
🚨 Warning: This pull request contains Frontend and Backend changes! It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently. Have questions? Please ask in the |
Move the 30-day trace age check from explore/tables/tracesTable/utils to a shared location at utils/trace/isOlderThan30Days. Add timestamp normalization to correctly handle both seconds and milliseconds. Create a reusable DisabledTraceLink component that renders muted text with a tooltip for links to traces older than 30 days. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…surfaces Add 30-day age checks to trace and span links across issue details, discover, dashboards, logs, agents, transaction summary, and trace drawer. Links to traces older than 30 days now render as disabled text with a tooltip instead of broken clickable links. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…samples surfaces Add 30-day age checks to trace links in insights modules (web vitals, mobile, agents), span samples tables, span summary sample list, metrics samples, and trace drawer span attributes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… event surfaces Add 30-day age checks to trace links in profiling headers, flamegraph, profile events table, span evidence key-value list, profile event evidence, and statistical detector event display. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The constant is only used internally within the module. Removing the export fixes the knip unused-export warning. Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
Accept undefined in isPartialSpanOrTraceData to match callers that pass number | undefined timestamps. Add missing disabled prop to DropdownItemProps in tagsHeatMap and pass it through to MenuItem. Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
The isPartialSpanOrTraceData check was using the current span's timestamp to decide whether to disable links to other traces. Span links connect to external traces that may have completely different ages, so a recent span could correctly link to an old trace while an old span could incorrectly have its links disabled even when the target traces are still within retention. Since TraceItemResponseLink does not carry the linked trace's timestamp, we cannot determine the target's age. Remove the check so links are always clickable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e view The trace view already has the trace loaded, so the trace ID attribute link in the span details drawer should always be clickable. The isPartialSpanOrTraceData check was incorrectly disabling the link based on the current span's age. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract the shared MinimapContainer block into a variable and conditionally wrap it with a Link, removing ~15 lines of duplicated JSX that could drift apart during future edits. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move DisabledTraceLink from components/links/ to components/explore/ where it better fits with other explore-related components. Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
The isOld check ran before the isIssue check, preventing issue event
links from being generated for events older than 30 days. Issue event
links (/issues/{id}/events/{eventId}/) do not depend on trace data
and should always be available regardless of age.
Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
The 'View in Full Trace' button was disabled for traces older than 30 days but provided no explanation to the user. Wrap the button in a Tooltip that shows 'Trace data is only available for the last 30 days', matching the pattern used in other disabled trace links in this PR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the isPartialSpanOrTraceData re-export from tracesTable/utils since fieldRenderers.tsx was still importing from that indirection. Update fieldRenderers.tsx to import directly from the canonical location (sentry/utils/trace/isOlderThan30Days) and fix the Tooltip import in drawer.tsx to use @sentry/scraps/tooltip. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move isOld check and traceViewLink computation into the id key branch where they are actually used. The SPAN_DESCRIPTION branch never references traceViewLink, so computing it there was wasted work and required a non-null assertion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use the event timestamp when profile evidence omits trace timing and block Discover transaction IDs once trace data ages out. Normalize numeric string timestamps so the 30-day guard behaves consistently. Co-Authored-By: GPT-5.4 <noreply@openai.com> Made-with: Cursor
0666dda to
3354073
Compare
Wrap the disabled old-trace ID cell in the same overflow container as the other web vitals table states so narrow columns still ellipsize consistently. Co-Authored-By: GPT-5.4 <noreply@openai.com> Made-with: Cursor
Prevent navigation to trace details for events older than 30 days in both projectEventRedirect and discover eventDetails pages. Shows a retention message instead of redirecting.
Disable the "View Full Trace" button with a tooltip and hide the issues trace waterfall overlay when events are older than 30 days.
Use DisabledTraceLink in trace drawer attributes, span links, and trace summary sections when data is older than 30 days.
Disable trace column links in discover transactionsTable, EAP sampled events table, and transaction summary link generators when data is older than 30 days.
Use >= instead of > for the retention check so data at exactly 30 days is conservatively marked as old, preventing broken links in the boundary window. Expand test coverage from 3 to 10 cases including ISO strings, numeric types, boundary, undefined, and future timestamps. Extract IIFE in profileDetails to a local variable for readability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
location.query.timestamp can be string | string[], but isPartialSpanOrTraceData expects string | number | undefined. Extract and normalize the value before passing it to the function. Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
…imestamp Move the `isOld` computation outside the `.flatMap()` loop in traceSpanLinks since `node.value.start_timestamp` is constant across iterations. Add JSDoc to `normalizeTimestamp` documenting expected input formats and known edge case with pure numeric date strings.
- Add DisabledTraceLink fallback in ProfileEventDetails for old transactions - Add tooltip to disabled dropdown items in tagsHeatMap - Remove redundant && guard before isPartialSpanOrTraceData calls since the utility already returns false for undefined
Events with a groupID and eventID redirect to the issue event page, so the old-trace check should not block them. Extract the redirect condition into a variable and gate the error screen accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
Replace plain container with DisabledTraceLink for trace IDs when the transaction timestamp indicates old/partial data, consistent with the app-wide pattern for disabling links to old traces. Refs EXP-647 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ates In the Web Vitals detail panel, the disabled trace link was showing the span ID (row.id) while the active link showed the trace ID (row.trace), causing the same column to display different identifiers depending on data age. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…k disable feature TransactionEventBuilder defaulted startTimestamp to 0 (epoch), which isPartialSpanOrTraceData correctly identifies as old data (>30 days), disabling the 'View Full Trace' button. Add dateCreated with a current timestamp so the isOld check sees a recent event, leaving startTimestamp and endTimestamp unchanged for duration calculations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit fc10990. Configure here.
| await userEvent.hover(button); | ||
| expect( | ||
| await screen.findByText('Trace data is only available for the last 30 days') | ||
| ).toBeInTheDocument(); |
There was a problem hiding this comment.
Test expects wrong tooltip text from DisabledTraceLinkTooltip
Medium Severity
The tests assert the tooltip text is "Trace data is only available for the last 30 days", but the DisabledTraceLinkTooltip component actually renders "Trace is older than 30 days" (from disabledTraceLink.tsx line 35). The component wrapping the LinkButton in eventTraceView.tsx and profileEventEvidence.tsx uses DisabledTraceLinkTooltip, so these tests will fail due to the string mismatch.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit fc10990. Configure here.


Trace data has a 30-day retention window. When users click trace links for data older than 30 days, they land on broken/empty trace waterfall pages. This PR disables those links across the entire frontend, showing muted text with a tooltip instead.
Foundation:
isPartialSpanOrTraceData()fromexplore/tables/tracesTable/utilsto a sharedutils/trace/isOlderThan30Daysmodule with proper timestamp normalization (seconds vs milliseconds detection)DisabledTraceLinkcomponent (andDisabledTraceLinkTooltipvariant) that renders muted text with a tooltip explaining the 30-day limit, optionally linking to similar recent eventsprojectEventRedirectguard so navigating directly to an old event URL via the redirect view doesn't land on a broken page~50 files updated across all trace link surfaces:
Fixes EXP-647